package com.vae.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.vae.porperty.MinioClientProperties;
import com.vae.service.MinioService;
import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * Minio 服务实现类
 */
@Service
public class MinioServiceImpl implements MinioService {
    @Autowired
    private MinioClient minioClient;
    @Autowired
    private MinioClientProperties minioClientProperties;

    /**
     * 上传文件
     * @param file
     * @return
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception{
        // 判断bucket是否存在
        boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(minioClientProperties.getBucketName())
                .build());
        if (!bucketExists) {
            //创建bucket
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(minioClientProperties.getBucketName())
                    .build());
        }

        // 设置bucket权限（自己读写，所有人读）
        minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
                .bucket(minioClientProperties.getBucketName())
                .config(this.createBucketPolicyConfig(minioClientProperties.getBucketName()))
                .build());

        // 上传文件
        // String url = minioProperties.getEndpoint() + "/" + minioProperties.getBucketName() + "/" + fileName;
        String fileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date())
                + "/" + UUID.randomUUID() + file.getOriginalFilename();

        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioClientProperties.getBucketName())
                .stream(file.getInputStream(), file.getSize(), -1)
                .object(fileName)
                .contentType(file.getContentType())
                .build());

        // String.join(delimiter, elements) delimiter: 分隔符 elements: 可变长度元素
        return String.join("/", minioClientProperties.getEndpoint(), minioClientProperties.getBucketName(), fileName);
    }

    // 创建minio bucket权限
    private String createBucketPolicyConfig(String bucketName) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode policyNode = mapper.createObjectNode();
        policyNode.put("Version", "2012-10-17");

        ArrayNode statementArray = mapper.createArrayNode();
        ObjectNode statementNode = mapper.createObjectNode();
        statementNode.put("Effect", "Allow");
        statementNode.put("Action", "s3:GetObject");
        statementNode.put("Principal", "*");  // Consider specifying a more restrictive principal
        statementNode.put("Resource", String.format("arn:aws:s3:::%s/*", bucketName));

        statementArray.add(statementNode);
        policyNode.set("Statement", statementArray);
        return mapper.writeValueAsString(policyNode);
    }
}
